<!-- scroll-list.vue (Vue 3 Composition API with <script setup>) -->
<template>
  <!-- 模板部分基本保持不变，因为 Vue 3 的模板语法是高度兼容的 -->
  <div :style="scrollListWrapStyle" class="scroll-list-wrap">
    <scroll-view :lower-threshold="50" :scroll-with-animation="true" :scroll-y="true" :style="listWrapStyle" class="scroll-div" @scroll="handleScroll" @scrolltolower="handleScrolltolower" @touchend="handleTouchEnd" @touchmove="handleTouchMove" @touchstart="handleTouchStart">
      <div :style="scrollContentStyle" class="scroll-content">
        <!-- 下拉刷新区域 -->
        <div v-if="showPullDown" :style="refreshViewStyle" class="pull-down-wrap">
          <div class="refresh-div">
            <div :class="{ refreshing: refreshing }" :style="pullDownAnimationStyle" class="pull-down-animation"></div>
            <div class="pull-down-text">{{ refreshText }}</div>
          </div>
        </div>

        <!-- 列表内容插槽 -->
        <slot></slot>

        <!-- 上拉加载区域 -->
        <div v-if="showPullUp" class="pull-up-wrap">
          <div class="load-div">
            <div v-if="loading" class="pull-up-animation"></div>
            <div class="pull-up-text">{{ loadText }}</div>
          </div>
        </div>
        <div v-if="showEmpty" class="empty-wrap" style="padding : 200rpx 0;">
          <un-data style="height: 100%"></un-data>
        </div>
      </div>
    </scroll-view>
  </div>
</template>

<script setup>
// 1. 导入所需的 Vue 3 API
import { ref, reactive, computed, watch, onMounted } from 'vue';
import UnData from '@/components/un-data/UnData.vue';

// 2. 定义 Props (替代 Vue 2 的 props 选项)
// defineProps 是一个编译器宏，不需要从 vue 导入
const props = defineProps({
  // 是否启用下拉刷新
  pullDownRefresh: {
    type: Boolean,
    default: false,
  },
  // 是否启用上拉加载
  pullUpLoad: {
    type: Boolean,
    default: true,
  },
  // 是否正在加载中
  loading: {
    type: Boolean,
    default: false,
  },
  // 是否已加载全部
  finished: {
    type: Boolean,
    default: false,
  },
  // 是否显示空状态
  showEmpty: {
    type: Boolean,
    default: false,
  },
  // 空状态图片
  emptyImage: {
    type: String,
    default: '',
  },
  // 空状态文本
  emptyText: {
    type: String,
    default: '暂无数据',
  },
  // 自定义样式
  height: {
    type: [String, Number],
    default: '100%',
  },
  // 自定义背景色
  background: {
    type: String,
    default: '#f7f8fa',
  },
});

// 3. 定义 Emits (替代 Vue 2 的 this.$emit)
// defineEmits 也是一个编译器宏
const emit = defineEmits(['refresh', 'load']);

// 4. 将 data 中的属性转换为响应式变量
// 基本类型使用 ref()
const startY = ref(0);
const isPullingDown = ref(false);
const isPullingUp = ref(false);
const beforeScrollTop = ref(0);
const refreshing = ref(false);

// 对象类型使用 reactive()
const pullDownStyle = reactive({
  height: '0px',
  position: 'absolute',
  top: '0px',
  left: '0px',
  right: '0px',
  overflow: 'hidden',
});

// 5. 将 computed 属性转换为 computed() 函数
const showPullDown = computed(() => props.pullDownRefresh);
const showPullUp = computed(() => props.pullUpLoad && !props.showEmpty);
const scrollListWrapStyle = computed(() => ({
  height: typeof props.height === 'number' ? `${props.height}px` : props.height,
}));
const listWrapStyle = computed(() => ({
  background: props.background,
}));
const scrollContentStyle = computed(() => ({
  transform: `translate3d(0, ${pullDownStyle.height}, 0)`,
  transition: isPullingDown.value ? 'none' : 'transform 0.3s',
}));
const refreshViewStyle = computed(() => ({
  height: `${props.refreshHeight || 50}px`,
}));
const pullDownAnimationStyle = computed(() => ({
  transform: `rotate(${isPullingDown.value ? 180 : 0}deg)`,
}));
const refreshText = computed(() => {
  if (refreshing.value) return '正在刷新...';
  if (isPullingDown.value) return '释放立即刷新';
  return '下拉可以刷新';
});
const loadText = computed(() => {
  if (props.finished) return '没有更多了';
  if (props.loading) return '加载中...';
  if (isPullingUp.value) return '释放加载更多';
  return '上拉加载更多';
});

// 6. 将 methods 转换为普通函数
const handleTouchStart = (event) => {
  if (props.pullDownRefresh) {
    startY.value = event.touches[0].clientY;
  }
};

const handleTouchMove = (event) => {
  if (!props.pullDownRefresh) return;
  const currentY = event.touches[0].clientY;
  const distance = currentY - startY.value;
  if (distance > 0 && beforeScrollTop.value === 0) {
    event.preventDefault();
    isPullingDown.value = true;
    pullDownStyle.height = `${Math.min(distance, props.refreshHeight || 50)}px`;
  }
};

const handleTouchEnd = () => {
  if (!props.pullDownRefresh) return;
  if (isPullingDown.value) {
    if (pullDownStyle.height === `${props.refreshHeight || 50}px`) {
      refreshing.value = true;
      emit('refresh');
    } else {
      pullDownStyle.height = '0px';
    }
    isPullingDown.value = false;
  }
};

const handleScroll = (event) => {
  beforeScrollTop.value = event.detail.scrollTop;
};

const handleScrolltolower = () => {
  console.log('handleScrolltolower', { finished: props.finished, loading: props.loading, pullUpLoad: props.pullUpLoad})
  if (!props.pullUpLoad || props.loading || props.finished) return;
  isPullingUp.value = true;
  emit('load');
};

// 7. 将 watch 选项转换为 watch() 函数
// 监听 loading 变化，以重置上拉状态
watch(
  () => props.loading,
  (newVal) => {
    if (!newVal) {
      isPullingUp.value = false;
    }
  },
);

// 8. 将生命周期钩子转换为 onMounted()
// 在这里可以执行组件挂载后的初始化逻辑
onMounted(() => {
  console.log('Scroll list component mounted.');
});
defineExpose({});
</script>

<!-- style 部分完全不需要改动 -->
<style lang="scss" scoped>
.scroll-list-wrap {
  position: relative;
  overflow: hidden;
  background: red;

  .scroll-div {
    height: 100%;
    overflow: hidden;
  }
  .scroll-content {
    min-height: 100%;
  }
  .pull-down-wrap {
    display: flex;
    justify-content: center;
    align-items: center;

    .refresh-div {
      margin: auto;
      display: flex;
      align-items: center;
      .pull-down-animation {
        width: 32rpx;
        height: 32rpx;
        border-width: 4rpx;
        border-style: solid;
        border-color: #666 transparent transparent transparent;
        border-radius: 50%;
        transition: transform 0.2s;
        &.refreshing {
          animation: spin 0.8s linear infinite;
        }
      }
      .pull-down-text {
        margin-left: 10rpx;
        font-size: 28rpx;
        color: #666;
      }
    }
  }

  .empty-div {
    margin: auto;
    display: flex;
    align-items: center;
    flex-direction: column;
    .empty-image {
      width: 200rpx;
      height: 200rpx;
    }
    .empty-text {
      color: #606266;
      margin-top: 20rpx;
    }
  }
  .list-content {
  }
  .pull-up-wrap {
    display: flex;
    align-items: center;
    justify-content: center;

    .load-div {
      padding: 20rpx 0;
      display: flex;
      align-items: center;
      justify-content: center;
      .pull-up-animation {
        width: 32rpx;
        height: 32rpx;
        border-width: 4rpx;
        border-style: solid;
        border-color: #666 transparent transparent transparent;
        border-radius: 50%;
        animation: spin 0.5s linear infinite;
      }
      .pull-up-text {
        margin-left: 10rpx;
        font-size: 28rpx;
        color: #666;
      }
    }
  }
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>
